#include "StdAfx.h"
#include "Card.h"

using namespace SHGame;

/*
* Returns the value of this card. 
* The value is the "point value" in the game of Sheepshead.
*/
int Card::getValue() {
	switch (this->getFace()) {
		case Card::Face::Ace:
			return 11;
		case Card::Face::Ten:
			return 10;
		case Card::Face::King:
			return 4;
		case Card::Face::Queen:
			return 3;
		case Card::Face::Jack:
			return 2;
		default:
			return 0;
	}
}

/*
* Returns the suit of this card
*/
Card::Suit Card::getSuit() {
	return this->suit;
}

/*
* Returns the face of this card
*/
Card::Face Card::getFace() {
	return this->face;
}

/*
* Returns true if this card is "on suit" with the given card.
* To be on suit, both cards must be of the same suit (i.e. spades or hearts).
* All trump cards are only on suit with other trump cards; this method will
* consider two cards onsuit if they are trump.
*/
bool Card::onSuit(Card ^card) {
	if (this->isTrump() || card->isTrump())
		return card->isTrump() == this->isTrump();
	return this->suit == card->suit;
}

/*
* Returns true if this card is "on suit" with the given suit.
* To be on suit, this card must be of the same suit (i.e. spades or hearts).
* This method does not take Trump into consideration. 
*/
bool Card::onSuit(Card::Suit suit) {
	if (this->isTrump())
		return false;
	return this->getSuit() == suit;
}

/*
* Returns true if this card is a trump card.
* To be a trump card it must be a diamond, jack, or queen
*/
bool Card::isTrump() {
	// see if the suit is a diamond
	if (this->getSuit() == Card::Suit::Diamonds)
		return true;
	// see if its a queen
	if (this->getFace() == Card::Face::Queen)
		return true;
	// see if its a Jack
	if (this->getFace() == Card::Face::Jack)
		return true;
	// else, its not trump
	return false;
}

bool Card::Equals(Card ^ card) {
	return this->suit == card->suit &&
		this->face == card->face;
}

System::String^ Card::toString() {
	System::String ^str = gcnew System::String("");
	str = System::String::Concat("Card[",this->face," of ", this->suit,"]");
	return str;
}

int Card::getRank() {
	int rank = 1;
	if (this->isTrump()) {
		// compute trump value:
		int faceRank = Card::findIndex(Card::FACES, this->face);
		rank += 1000;
		rank += 8 * (20 - faceRank);
		rank += (5 - Card::findIndex(Card::SUITS, this->suit));
	} else {
		// compute fail value:
		int faceRank = Card::findIndex(Card::FACES, this->face);
		int suitRank = Card::findIndex(Card::SUITS, this->suit);
		rank += suitRank * 20;
		rank += (20 - faceRank);
	}
	return rank;
}

int Card::findIndex(array<Face> ^arr, Face f) {
	for (int i = 0; i < arr->Length; i++) {
		if (arr[i] == f)
			return i;
	}
	return -1;
}
int Card::findIndex(array<Suit> ^arr, Suit f) {
	for (int i = 0; i < arr->Length; i++) {
		if (arr[i] == f)
			return i;
	}
	return -1;
}

int Card::GetIndex() {
	return Card::findIndex(Card::FACES, this->face) * 4 + Card::findIndex(Card::SUITS, this->suit);
}

int Card::GetPickRating()
{
	return Card::RATINGS[this->GetIndex()];
}

bool Card::Takes(Card^ c)
{
	if (this->isTrump() || ! c->isTrump())
		return true;
	if (! this->isTrump() || c->isTrump())
		return false;
	if (!this->isTrump() || ! c->isTrump()) {
		if (this->suit == c->suit) {
			return this->getRank() > c->getRank();
		} else
			return false;
	}
	// they are both trump
	return this->getRank() > c->getRank();
}